package com.ruoyi.boat.aop;

import com.ruoyi.boat.domain.Boat;
import com.ruoyi.boat.service.IBoatService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.PageUtils.clearPage;
import static com.ruoyi.common.utils.PageUtils.startPage;

@Aspect
@Component
public class MyDataScopeAspect {

    @Autowired
    private IBoatService boatService;

    public static final String DATA_SCOPE = "dataScope";

    @Before("@annotation(myDataScope)")
    public void doBefore(JoinPoint point, MyDataScope myDataScope) {
        clearDataScope(point);
        handleDataScope(point, myDataScope);
    }

    protected void handleDataScope(final JoinPoint joinPoint, MyDataScope myDataScope) {
        // 获取当前的用户
        SysUser currentUser = ShiroUtils.getSysUser();
        if (currentUser != null) {
            // 如果是超级管理员，则不过滤数据
            if (!currentUser.isAdmin()) {
                dataScopeFilter(joinPoint, myDataScope);
            }
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint 切点
     */
    public void dataScopeFilter(JoinPoint joinPoint, MyDataScope myDataScope) {
        clearPage(); // 先清除分页，获取全部艇
        List<String> boatCodes = boatService.selectBoatList(new Boat()).stream().map(Boat::getCode).collect(Collectors.toList());
        startPage(); // 再分页，获取分页状态
        String sqlString = StringUtils.format(" and {} in ({})", myDataScope.value(), Strings.join(boatCodes, ','));
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, sqlString);
        }
    }

    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }
}
